﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MossmanMill.DataModel
{
    /// <summary>
    /// Database Access (DAO Gateway) Interface
    /// </summary>
    /// <dates>
    /// 22/05/2012 - created
    /// </dates>
    public interface IDatabaseAccess
    {

        /// <summary>
        /// Get a list of Room Locations (these rooms hold racks)
        /// </summary>
        /// <returns>A list of Rooms</returns>
        List<Room> GetRooms();

        /// <summary>
        /// Get a room by it's Id
        /// </summary>
        /// <param name="id">Room Id</param>
        /// <returns>The Room associated with the Id, or null if it doesn't exist</returns>
        Room GetRoom(int id);

        /// <summary>
        /// Add a new Room to the database
        /// </summary>
        /// <param name="name">Room name</param>
        /// <param name="location">A 2D point in string format: "x,y"</param>
        /// <returns>True if successful</returns>
        bool AddRoom(string name, string location);

        void UpdateRoom(Room room);

        /// <summary>
        /// Add a new Rack to the database
        /// </summary>
        /// <param name="id">Room Id</param>
        /// <param name="model">Rack Model Name</param>
        /// <param name="address">Rack Address String eg "CPM0101"</param>
        /// <returns>True if successful</returns>
        bool AddRack(int id, string model, string address);

        /// <summary>
        /// Get a list of all racks
        /// </summary>
        /// <returns>List of racks</returns>
        List<Rack> GetRacks();

        Rack GetRack(int rackId);

        List<Rack> GetRacks(int room);

        /// <summary>
        /// Get the slottable in a certain slot on a rack
        /// </summary>
        /// <param name="rack">Rack Id</param>
        /// <param name="slot">Slot Position</param>
        /// <param name="look1">Looking for Processor</param>
        /// <param name="look2">Looking for Processor part 2</param>
        /// <returns>A slottable</returns>
        Slottable GetSlottable(int rack, int slot, bool look1 = false, bool look2 = false);

        /// <summary>
        /// Get a list of slottables
        /// </summary>
        /// <param name="rack">Rack to get slottables from. If null, it will get all slottables</param>
        /// <returns>A List of Slottables</returns>
        List<Slottable> GetSlottables(Rack rack = null);

        /// <summary>
        /// Get all Sensors
        /// </summary>
        /// <returns>A list of sensors</returns>
        List<Sensor> GetSensors(Card card = null);

        /// <summary>
        /// Get cards that can be used. (The inventory of IOModule cards)
        /// </summary>
        /// <returns>List of Cards with no Card/Slot Ids</returns>
        List<Card> GetAvailableCards();

        /// <summary>
        /// Get a card associated with slottable
        /// </summary>
        /// <param name="slotId">Slottable Id</param>
        /// <returns>Card</returns>
        Card GetCard(int slotId, int rackId, int pos);

        Card GetCard(int cardId);

        Sensor GetSensor(int card, int channel);

        /// <summary>
        /// Get a list of distinct Rack models
        /// </summary>
        /// <returns></returns>
        List<string> GetRackModels();

        /// <summary>
        /// Get a list of distict Network Card Model
        /// </summary>
        /// <returns></returns>
        List<string> GetNetworkCardModels();

        /// <summary>
        /// Get a list of distinct Processor Models
        /// </summary>
        /// <returns></returns>
        List<string> GetProcessorModels();

        /// <summary>
        /// Add a new Network Card
        /// </summary>
        /// <param name="rack">Rack Id</param>
        /// <param name="position">Slot Position</param>
        /// <param name="model">Network Card Model</param>
        /// <param name="type">'U'/'D' Upstream (connections back to server or another Rack)</param>
        /// <param name="conn">Other NetworkCard Id (I want to change this to other Rack Id) </param>
        void AddNetworkCard(int rack, int position, string model, char type, int conn);

        /// <summary>
        /// Add a new Processor
        /// </summary>
        /// <param name="rack">Rack Id</param>
        /// <param name="position">Slot Position</param>
        /// <param name="model">Model Name</param>
        void AddProcessor(int rack, int position, string model);

        /// <summary>
        /// Add new IOModule
        /// </summary>
        /// <param name="model">Model Name</param>
        /// <param name="type">DO,DI,AO,AI,OTHER</param>
        /// <param name="channels">Number of channels</param>
        /// <param name="desc">Description</param>
        void AddIOModule(string model, int type, int channels, string desc);

        /// <summary>
        /// Add new Card
        /// </summary>
        /// <param name="rack">Rack Id</param>
        /// <param name="position">Slot Position</param>
        /// <param name="module">Module Id</param>
        void AddCard(int rack, int position, int module);

        void AddSensor(Sensor sensor);

        void updateSensor(int sensor, string tag, string param, string desc);

        /// <summary>
        /// Swap a card with another module
        /// </summary>
        /// <param name="card">Card Id</param>
        /// <param name="module">New Module Id</param>
        void ChangeCard(int card, int module);

        /// <summary>
        /// Kill a slottable and it's child
        /// </summary>
        /// <param name="rack">Rack Id</param>
        /// <param name="slot">Slot Position</param>
        void DeleteSlottable(int rack, int slot);

        /// <summary>
        /// Delete All Table Data for Inital Data Loading
        /// </summary>
        void DeleteAllTableData();

        /// <summary>
        /// Get CPM report data set from database
        /// <returns>CPM report data set</returns>
        /// </summary>
        List<CpmReport> GetCpmReport();

        List<Card> GetCards(Rack rack = null);

        List<NetworkCard> GetNetworkCards(Rack rack = null);

        List<Processor> GetProcessors(Rack rack = null);

        /// <summary>
        /// Create a new rack in the database using all components of the rack.
        /// Returns the added rack.
        /// </summary>
        /// <param name="rack"></param>
        Rack AddRack(Rack rack);

        void UpdateRack(Rack rack);
    }
}
